package team.nmsg.ge.system.util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;

 
/**
 * 包工具，借用spring 提供扫描工具包 
 */
public class PackageUtil {
 
    private final static Logger log = LoggerFactory.getLogger(PackageUtil.class);
 
    public static final String CLASS_FILE_SUFFIX = ".class";
    
    /**
     * 扫描指定包 下 所有class
     * @param pgkName
     * @param parentClass
     * @param annoClass
     * @return
     */
    public static List<Class<?>> getClasses(String pgkName , Class parentClass , Class annoClass ){
    	try {
    		ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
    		PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(contextClassLoader);
    		MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
    		String replaceAll = pgkName.replace(".", "/");
    		String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX+replaceAll+"/**/*.class";
    		
    		Resource[] resources = resolver.getResources(packageSearchPath);
    		if( resources.length>0 ){
    			List<Class<?>> classes = new ArrayList<Class<?>>();
    			for( int i=0; i<resources.length ;i++ ){
    				 MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resources[i]);
    				 String className = metadataReader.getClassMetadata().getClassName();
    				 
    				Class<?> loadClass = contextClassLoader.loadClass( className );
    				if( parentClass != null && !parentClass.isAssignableFrom(loadClass) ){
    					continue;
    				}
       				if( annoClass != null && !loadClass.isAnnotationPresent(annoClass) ){
    					continue;
    				}
    				classes.add(loadClass);
    			}
    			return classes;
    		}
		} catch (Exception e) {
			e.printStackTrace();
			log.error("" , e);
		}
    	return Collections.emptyList();
    }
    
    public static List<Class<?>> getClasses(String pgkName ){
    	return getClasses(pgkName , null , null);
    }
    
    public static List<Class<?>> getClassesWithAnno(String pgkName , Class annoClass ){
    	return getClasses(pgkName , null , annoClass);
    }
    
    public static List<Class<?>> getClassesWithParent(String pgkName , Class parentClass ){
    	return getClasses(pgkName , parentClass , null);
    }
    
    
    public static void main(String[] args) {
		
	}
 
}